#include "adr/Metadata/BaseProperty.h"
#include "adr/Metadata/ValidationAttribute.h"

#include <algorithm>

namespace adr {
	using namespace std;

	BaseProperty::BaseProperty(const string& name, const string& displayName) 
		: name(name), displayName(displayName), validationErrors() {
	}

	BaseProperty::~BaseProperty() {}

	const string& BaseProperty::GetDisplayName() const {
		return this->displayName;
	}

	const string& BaseProperty::GetName() const {
		return this->name;
	}

	const vector<string>& BaseProperty::GetValidationErrors() const {
		return this->validationErrors;
	}
	
	void BaseProperty::ClearValidationErrors() {
		this->validationErrors.clear();
	}

	void BaseProperty::AddAttribute(Attribute* attrib) {
		this->attributes.push_back(attrib);
	}

	Attribute* BaseProperty::GetAttributeByName(const string& attribName) {
		auto it = find_if(
			begin(this->attributes),
			end(this->attributes),
			[&](Attribute* attr) {
			return attr->GetName() == attribName;
		});

		if (it == end(this->attributes)) {
			return nullptr;
		}

		return *it;
	}

	bool BaseProperty::IsValid() const {
		return this->validationErrors.size() == 0;
	}

	bool BaseProperty::Validate() {
		this->ClearValidationErrors();
		for_each(
			begin(this->attributes),
			end(this->attributes),
			[&](Attribute* attr) {
			ValidationAttribute* validationAttr = dynamic_cast<ValidationAttribute*>(attr);
			if (validationAttr != nullptr) {
				validationAttr->Validate(*this);
			}
		});

		return this->IsValid();
	}
}